/**
 * Urban Parks 
 *
 * Team M&M'S 
 * Michael Pogson
 * Michael Satran Jr.
 * Stephen Hunter
 * 
 * Date: ${date}
 */

package controller;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import model.Date;
import model.Job;
import model.Park;
import model.ParkManager;
import model.User;
import model.Volunteer;

/**
 * 
 * @author Michael Pogson
 * @version Winter 2012
 */
public class Controller {
	
	/**
	 * A Master Map that contains all the users in the system.
	 */
	private Map<String, User> my_user_map = new HashMap<String, User>();
	
	/**
	 * A collection of all the volunteers for ease of access.
	 */
	private Collection<Volunteer> my_volunteer_list = new ArrayList<Volunteer>();
	
	/**
	 * The current user of the system.
	 */
	private User my_current_user;
	
	/**
	 * A collection of all the parks in the system for ease of access.
	 */
	private Collection<Park> my_park_list = new ArrayList<Park>();
	
	/**
	 * The current total number of jobs in the system.
	 */
	private int my_total_jobs;
	
	/**
	 * Number of months allowed to schedule jobs out. 
	 */
	private static final int NUM_OF_MONTHS = 90;
	
	/**
	 * max number of jobs allowed at one time.
	 */
	private static final int MAX_NUMBER_OF_JOBS = 30;
	
	/**
	 * max number of jobs allowed in one week.
	 */
	private static final int MAX_JOBS_IN_WEEK = 5;
	
	/**
	 * Max length of job.
	 */
	private static final int MAX_NUMBER_OF_DAYS = 2;
	
	/*
	 * @pre the_user_map != null
	 * @Pre the_volunteer_list != null
	 * @pre the_park_list != null
	 * 
	 * @post my_user_map != null
	 * @post my_volunteer_list !=null
	 * @post my_park_list != null
	 * @post my_total_jobs == total current jobs
	 * @post my_current_user == null
	 */
	/**
	 * 
	 * The constructor for the controller object.
	 * 
	 * @param the_user_map This is passed in from parsing a file. Master List of users.
	 * @param the_volunteer_list this is passed in from parsing a file. List of all volunteers.
	 * @param the_park_list this is passed in from parsing a file. list of all parks.
	 */
	public Controller(final Map<String,User> the_user_map, final Collection<Volunteer> the_volunteer_list, 
						final Collection<Park> the_park_list) {
		
		my_user_map.putAll(the_user_map);
		my_volunteer_list.addAll(the_volunteer_list);
		my_park_list.addAll(the_park_list);
		my_total_jobs = 0;
		my_current_user = null;
		setTotalJobs();
	}
	
	/*
	 * @pre the_email != null
	 * @pre the_email !isEmpty()
	 * 
	 * @post my_current_user != @pre my_current_user
	 */
	/**
	 * This method sets the current user to whatever email that is entered into the gui. If the 
	 * email is invalid an exception is thrown back to the gui to re-enter the email.
	 * @param the_email the email entered at the gui.
	 * @throws IllegalArgumentException if the email is null,empty, or if the user was not found.
	 */
	public void setCurrentUser(final String the_email) throws IllegalArgumentException {
		
		if(the_email == null) {
			
			throw new IllegalArgumentException("Email cannot be NULL!");
		
		} else if(the_email.isEmpty()) {
			
			throw new IllegalArgumentException("Please Enter an email!");
		
		} else {
		
			my_current_user = my_user_map.get(the_email);
		}
		
		if(my_current_user == null) {
			
			throw new IllegalArgumentException("User E-mail not valid. Please enter a vaild E-mail!");
		}
	}
	
	/*
	 * 
	 * @post returns the current state of the user.
	 */
	/**
	 * This returns the state of the current user.
	 * @return the current user of the system.
	 */
	public User getCurrentUser() {
		
		return my_current_user;
	}
	
	/*
	 * @pre job != null
	 * @pre the_park != null
	 * @pre the_par !isEmpty()
	 * @post job is added to park
	 * @post number of jobs increases by 1
	 */
	
	/**
	 * 
	 * This method adds the job to the park IFF the job passes its tests and
	 * the park passes its tests.
	 * @param the_job the job to be added to the jobs list held by a park
	 * @param the_park the park that the job needs to be added to.
	 * @throws IllegalArgumentException if the park is not found, if park is null or empty, or if something is wrong with job.
	 */
	public void addJob(final Job the_job, final String the_park) throws IllegalArgumentException{
		
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		boolean answer = false;
		
		checkValidJob(the_job);
		checkPark(the_park);
			for(int i = 0; i < parks.size(); i++){
			
				if(parks.get(i).getParkName().equalsIgnoreCase(the_park)) {
				
					parks.get(i).addJob(the_job);
					my_total_jobs++;
					answer = true;
				}
			}
			
		if(answer = false) {
			
			throw new IllegalArgumentException("Did not find park you were looking for!");
		}
		
	}
	
	/**
	 * Checks to make sure the park string is not null and is not empty!
	 * @param the_park the park that needs to be pulled out of the park list
	 * @return returns false if something is wrong with the park string, returns true if nothing is wrong.
	 */
	private void checkPark(final String the_park) throws IllegalArgumentException {
		
		if(the_park == null) {
		
			throw new IllegalArgumentException("Park cannot be null!");
		
		} else if(the_park.isEmpty()) {
		
			throw new IllegalArgumentException("Park name cannoth be empty!");
		}
	}
	
	/**
	 * This is a private method that checks the job against all the business rules for validity.
	 * @param the_job the job that wants to be added to the parks job list.
	 * @return returns true if the job can be added and false if something is wrong.
	 */
	private void checkValidJob(final Job the_job) throws IllegalArgumentException{
		
		Calendar cal = Calendar.getInstance();
		//System.out.println(currentDate);
		Date currentDate = new Date(cal.get(cal.MONTH) + 1, cal.get(cal.DATE), cal.get(cal.YEAR));		
		System.out.println(currentDate);
		   		if(the_job == null) {
		   			
		   			throw new IllegalArgumentException("Job cannot be null!");
		   			
				}
		   		if(my_total_jobs == MAX_NUMBER_OF_JOBS) { //total jobs cannot be more than 30
					
					throw new IllegalArgumentException("We allready have 30 jobs, sorry you cannot add more jobs!");
				
				}
		   		if(the_job.getJobLength() > MAX_NUMBER_OF_DAYS) { //jobs cannot last more than 2 days
					
					throw new IllegalArgumentException("Job cannot last more than 2 days!");
				
				}
		   		if(Math.abs(the_job.getStartDate().daysBetween(currentDate)) > NUM_OF_MONTHS) {
					
					throw new IllegalArgumentException("Job cannot be created more than 3 months ahead!");
				
				}
		   		if (checkWeek(the_job) > MAX_JOBS_IN_WEEK) {
					
					throw new IllegalArgumentException("We allready have " + MAX_JOBS_IN_WEEK + " jobs this week!");
				
				} else if (the_job.getStartDate().comesBefore(currentDate)) {
		   			
		   			throw new IllegalArgumentException("Cannot create a job in the Past, Marty!");
				}
	}
	
	/**
	 * This method checks the amount of jobs that are around a given jobs week.
	 * @param the_job the job that wants to be added
	 * @return an int that relates to the amount of jobs that are in the same week
	 * of the job that wants to be added.
	 */
	private int checkWeek(final Job the_job) {
		/*int num = 0;
		
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		
		for(int i = 0; i < parks.size(); i++) {
			
			ArrayList<Job> jobs = new ArrayList<Job>(parks.get(i).getJobs());
			
			for(int j = 0; j < jobs.size(); j++) {
				if(Math.abs(the_job.getStartDate().daysBetween(jobs.get(j).getStartDate())) <= 3) {
					
					num++;
				}
				
			}
		}
		System.out.println(num);
		return num;*/
		
		List<Job> jobs = (List<Job>) getAllJobs();

		Date start_date = the_job.getStartDate();

		Date start_week = start_date.nDaysEarlier(start_date.getDayOfWeek());

		int jobs_in_week = 1;
		for (int i = 0; i < 7; i++) {
			Date offset_start_date = start_week.nDaysLater(i);

			for (Job offset_job : jobs) {
				if (offset_job.getStartDate().equals(offset_start_date)) {
					jobs_in_week++;
				}
			}
		}

		//check jobs_in_week (Doesn't include the one currently adding!)
		return jobs_in_week;
	}
	
	/*
	 * @pre the_park != null
	 * @pre the_par !isEmpty()
	 * @pre the_job !=null
	 * @pre the_volunteer !=null
	 * 
	 * @post the_job will have a new volunteer added to its volunteer list if it can be added.
	 */
	/**
	 * This method adds the volunteer to a give job IFF he is allowed to by 
	 * our set rules.
	 * @param the_park the park that the job is located in.
	 * @param the_job the job the user wants to sign up for.
	 * @param the_volunteer the volunteer that wants to sign up for a job.
	 */
	public void addVolunteerToJob(final String the_park, final Job the_job) 
								   throws IllegalArgumentException {
		
		
		checkVolunteer((Volunteer)my_current_user, the_job);
		checkPark(the_park);
		boolean answer = false;
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		
		if(the_job == null) {
			throw new IllegalArgumentException("Job cannot be null!");
		}
		
		for(int i = 0; i < parks.size(); i++) {
			
		  if(parks.get(i).getParkName().equalsIgnoreCase(the_park)) {
				
				parks.get(i).addVolunteerToJob(the_job, (Volunteer)my_current_user);
				answer = true;
			}
		}
		if(answer == false) {
			
			throw new IllegalArgumentException("Park Name does not exist!");
		}
		
	}
	
	/**
	 * This method checks to make sure the volunteer can sign up for the job and that
	 * the job can be signed up for.
	 * @param the_volunteer the volunteer that wants to sign up for the job.
	 * @param the_job the job that the volunteer wants to sign up for.
	 * @throws IllegalArgumentException if the volunteer breaks one of the business rules.
	 */
	private void checkVolunteer(final Volunteer the_volunteer, final Job the_job) 
								throws IllegalArgumentException{
		
		Calendar cal = Calendar.getInstance();
		Date currentDate = new Date(cal.get(cal.MONTH +1), cal.get(cal.DATE), cal.get(cal.YEAR));
		
		
		if(the_volunteer == null) {
			
			throw new IllegalArgumentException("the_volunteer cannot be null");
		
		} else if(the_volunteer.isBlackBalled()) {
			
			throw new IllegalArgumentException("You are black balled sorry!");
		}
		
		checkVolunteerJobs(the_volunteer, the_job);
		
		
	}
	
	/**
	 * This method checks to see if the volunteer is already signed up for this job.
	 * @param the_volunteer the volunteer that wants to sign up for a job.
	 * @param the_job the job the volunteer wants to sign up for.
	 * @throws IllegalArgumentException if the volunteer trys to break a business rule.
	 */
	private void checkVolunteerJobs(final Volunteer the_volunteer, final Job the_job) 
									throws IllegalArgumentException{
		
				
		ArrayList<Volunteer> volunteers = new ArrayList<Volunteer>(the_job.getVolunteers());
		
			for(int k = 0; k < volunteers.size(); k++) {
			
				if(volunteers.get(k).equals(the_volunteer)) {
					
					throw new IllegalArgumentException("You are already signed up for this job!");
				}
			}
			
		ArrayList<Job> jobs = new ArrayList<Job>(getJobsForVolunteer());
		
		for(int i = 0; i < jobs.size(); i++) {
			
			if(jobs.get(i).getStartDate().equals(the_job.getStartDate())) {
				
				throw new IllegalArgumentException("You have allready signed up for a job on this date sorry!");
				
			}
		}
	}
	
	/*
	 * @pre: the_park != null
	 * @pre: the_park !isEmpty();
	 * 
	 * @post: list is restricted to jobs in the park.
	 */
	/**
	 * This method reduces the collection of jobs to whatever has the park name in it.
	 * @param the_park the park that the jobs need to belong to.
	 * @param the_jobs the collection of jobs that are currently being viewed.
	 * @return returns a collection of jobs that are only in the park.
	 */
	public Collection<Job> getOpenJobsByPark(final String the_park, final Collection<Job>the_jobs)
												throws IllegalArgumentException {
		ArrayList<Job> jobs = new ArrayList<Job>();
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		ArrayList<Job> currentJobs = new ArrayList<Job>(the_jobs);
		
		checkString(the_park);
		if(the_jobs == null) {
			throw new IllegalArgumentException("Jobs list cannot be null!");
		}
		
		for(int i = 0; i < parks.size(); i++) {
			
			if(parks.get(i).getParkName().equalsIgnoreCase(the_park)) {
				jobs.addAll(parks.get(i).getJobs());
			}
		}
			
			for(int i = 0; i < currentJobs.size(); i++) {
				
				if(!jobs.contains(currentJobs.get(i))){
					currentJobs.remove(i);
					i--;
				}
			}
			
			return currentJobs;
	}
	
	/*
	 * @pre: the_park != null
	 * @pre: the_park !isEmpty();
	 * 
	 * @post: list is restricted to jobs in the District.
	 */
	/**
	 * This method reduces the collection of jobs to whatever has the district name in it.
	 * @param the_district the district that the jobs need to belong to.
	 * @param the_jobs the collection of jobs that are currently being viewed.
	 * @return returns a collection of jobs that are only in the district.
	 */
	public Collection<Job> getOpenJobsByDistrict(final String the_district, final Collection<Job>the_jobs) 
												throws IllegalArgumentException {
		ArrayList<Job> jobs = new ArrayList<Job>();
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		ArrayList<Job> currentJobs = new ArrayList<Job>(the_jobs);
		
		checkString(the_district);
		if(the_jobs == null) {
			throw new IllegalArgumentException("Jobs cannot be null!");
		}
		
		for(int i = 0; i < parks.size(); i++) {
			
			if(parks.get(i).getDistrict().equalsIgnoreCase(the_district)) {
				jobs.addAll(parks.get(i).getJobs());
			}
		}
		
		for(int i = 0; i < currentJobs.size(); i++) {
			
			if(!jobs.contains(currentJobs.get(i))){
				currentJobs.remove(i);
				i--;
			}
		}
	
		return currentJobs;
	}
	
	/*
	 * @pre: the_region != null
	 * @pre: the_region !isEmpty();
	 * 
	 * @post: list is restricted to jobs in the region.
	 */
	/**
	 * This method reduces the collection of jobs to whatever has the park name in it.
	 * @param the_park the park that the jobs need to belong to.
	 * @param the_jobs the collection of jobs that are currently being viewed.
	 * @return returns a collection of jobs that are only in the park.
	 */
	public Collection<Job> getOpenJobsByRegion(final String the_region, final Collection<Job> the_jobs)throws IllegalArgumentException {
		
		ArrayList<Job> jobs = new ArrayList<Job>();
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		ArrayList<Job> currentJobs = new ArrayList<Job>(the_jobs);
		
		for(int i = 0; i < parks.size(); i++) {
			
			if(parks.get(i).getRegion().equalsIgnoreCase(the_region)) {
				jobs.addAll(parks.get(i).getJobs());
			}
		}
		for(int i = 0; i < currentJobs.size(); i++) {
			
			if(!jobs.contains(currentJobs.get(i))){
				currentJobs.remove(i);
				i--;
			}
		}
		return currentJobs;
	}
	
	
	/**
	 * This method really just checked region and district names for not null and empty!
	 * @param the_string the string begin checked for null or empty.
	 * @throws IllegalArgumentException thrown if string is null or empty.
	 */
	private void checkString(final String the_string) throws IllegalArgumentException{
		

		if(the_string == null) {
		
			throw new IllegalArgumentException(" cannot be null!");
		
		} else if(the_string.isEmpty()) {
		
			throw new IllegalArgumentException("cannot be empty!");
		}
		
	}
	
	/*
	 * @pre: the_volunteer != null
	 * 
	 * @post: the_volunteer.isBlackBalled() == true.
	 * @post: the_volunteer is removed from all jobs.
	 */
	/**
	 * This method turns the volunteer into a black balled volunteer.
	 * @param the_volunteer the volunteer to be black balled.
	 */
	public void blackBallVolunteer(final Volunteer the_volunteer)  throws IllegalArgumentException {
		
		if(the_volunteer == null) {
			throw new IllegalArgumentException("Volunteer cannot be null");
		}
		
		the_volunteer.blackBall();
	}
	
	/*
	 * @pre: the_volunteer != null
	 * 
	 * @post: the_volunteer.isBlackBalled() == false.
	 */
	/**
	 * This method unblackballs the volunteer, so they can sign up for jobs again.
	 * @param the_volunteer the volunteer to un black ball
	 * @throws IllegalArgumentException if the volunteer is null
	 */
	public void unBlackBallVolunteer(final Volunteer the_volunteer) throws IllegalArgumentException {
		
		if(the_volunteer == null) {
			throw new IllegalArgumentException("Volunteer cannot be null");
		}
		
		the_volunteer.unBlackBall();
		
	}
	
	/**
	 * This method goes through all the jobs and removes them.
	 * @param the_volunteer the volunteer to be removed.
	 */
	private void removeVolunteer(final Volunteer the_volunteer) throws IllegalArgumentException {
		
		ArrayList<Park> park = new ArrayList<Park>(my_park_list);
		ArrayList<Job> jobsinpark = new ArrayList<Job>();
		ArrayList<Volunteer> volunteers = new ArrayList<Volunteer>();
		
		if(the_volunteer == null) {
			throw new IllegalArgumentException("Volunteer cannot be null");
		}
		
		for(int i = 0; i < park.size(); i++) {
			jobsinpark.addAll(park.get(i).getJobs());
		}
		
		for(int i = 0; i < jobsinpark.size(); i++) {
			
			volunteers.addAll(jobsinpark.get(i).getVolunteers());
			
			for(int j = 0; j < volunteers.size(); j++) {
				/*if volunteer name equals name of volunteer in list*/
				if(volunteers.get(j).equals(the_volunteer)) {
					
					jobsinpark.get(i).removeVolunteer(the_volunteer);
				}
			}
			volunteers.clear();
		}
		
	}
	
	/*
	 * @pre my_volunteer_list !=null
	 * @pre my_volunteer_list !isEmpty()
	 * 
	 * @post a list of all black balled volunteers will be returned.
	 * 
	 */
	/**
	 * This method goes through the entire list of volunteers and retrieves all the volunteers
	 * that are black balled and adds them to a list.
	 * @return returns a list of all black balled volunteers.
	 */
	public Collection<Volunteer> getBlackBalledVolunteers() {
		ArrayList<Volunteer> temp_list = new ArrayList<Volunteer>(my_volunteer_list);
		Collection<Volunteer> black_ball_list = new ArrayList<Volunteer>();
		
		for(int i = 0; i < my_volunteer_list.size(); i++) {
			
			if(temp_list.get(i).isBlackBalled()) {
				black_ball_list.add(temp_list.get(i));
			}
		}
		return black_ball_list;
	}
	
	/*
	 * @pre my_current_user instanceof Volunteer
	 * 
	 * @post returns a collection of jobs connected to the volunteer
	 */
	/**
	 * This gets all the jobs related to the volunteer
	 * my_current_user will be a volunteer
	 * 
	 * @return returns a collection of jobs related to a volunteer
	 */
	public Collection<Job> getJobsForVolunteer() {
		
		ArrayList<Park> park = new ArrayList<Park>(my_park_list);
		ArrayList<Job> jobsinpark = new ArrayList<Job>();
		ArrayList<Volunteer> volunteers = new ArrayList<Volunteer>();
		ArrayList<Job> volunteerjobs = new ArrayList<Job>();
		
		for(int i = 0; i < park.size(); i++) {
			jobsinpark.addAll(park.get(i).getJobs());
		}
		
		for(int i = 0; i < jobsinpark.size(); i++) {
			
			volunteers.addAll(jobsinpark.get(i).getVolunteers());
			
			for(int j = 0; j < volunteers.size(); j++) {
				/*if volunteer name equals name of volunteer in list*/
		
				if(volunteers.get(j).getFirstName().equals(my_current_user.getFirstName()) && 
					volunteers.get(j).getLastName().equals(my_current_user.getLastName())) {
					
					volunteerjobs.add(jobsinpark.get(i));
				}
			}
			volunteers.clear();
		}
		return volunteerjobs;
	}
	
	
	
	
	/*
	 * @post returns the current state of the parks list.
	 */
	/**
	 * returns the current state of the parks list.
	 * @return returns current list of all the parks
	 */
	public Collection<Park> getParks() {
		
		return my_park_list;
	}
	
	/*
	 * @pre: my_park_list !=null
	 * 
	 * 
	 * @post returns a list of all the systems regions.
	 * 
	 */
	/**
	 * 
	 * This method gets all the regions thats are in the system.
	 * 
	 * @return returns a list of all the regions in system.
	 */
	public Collection<String> getRegions() {
		
		ArrayList<Park> temp_list = new ArrayList<Park>(my_park_list);
		Map<String, Integer> temp_map = new HashMap<String, Integer>();
		Park tempPark = null;
		
		for(int i = 0; i < my_park_list.size(); i++){
			
			tempPark = temp_list.get(i);
			if(temp_map.get(tempPark.getRegion()) == null) {
				temp_map.put(tempPark.getRegion(), 1);
			}
			
		}
		Collection<String> region_list = new ArrayList<String>(temp_map.keySet());
		return region_list;
	}
	
	
	/*
	 * @pre: my_park_list != null
	 * 
	 * @post returns all the districts in the system as a collection.
	 */
	/**
	 * This method gets all the districts in the system.
	 * @return returns a list of the districts in the system.
	 */
	public Collection<String> getDistricts() {
		ArrayList<Park> temp_list = new ArrayList<Park>(my_park_list);
		Map<String, Integer> temp_map = new HashMap<String, Integer>();
		Park tempPark = null;
		
		for(int i = 0; i < my_park_list.size(); i++){
			
			tempPark = temp_list.get(i);
			if(temp_map.get(tempPark.getDistrict()) == null) {
				temp_map.put(tempPark.getDistrict(), 1);
			}
			
		}
		Collection<String> district_list = new ArrayList<String>(temp_map.keySet());
		return district_list;
	}
	
	/*
	 * @pre: my_park_list != null
	 * 
	 * @post: returns a list of all jobs in the system.
	 */
	/**
	 * This method returns a collection of every job ever.
	 * @return returns a list of jobs
	 */
	public Collection<Job> getAllJobs() {
		
		Collection<Job> alljobs = new ArrayList<Job>();
		ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		
		for(int i = 0; i < parks.size(); i++) {
			
			alljobs.addAll(parks.get(i).getJobs());
		}
		
		return alljobs;
	}
	
	/*
	 * @pre: the_job !=null
	 * 
	 * @post: a list of volunteers will be returned
	 */
	/**
	 * This returns a collection of volunteers for a given job.
	 * @param the_job the job that has the wanted volunteers
	 * @throws IllegalArgumentException if the job is null
	 * @return returns a collection of volunteers
	 */
	public Collection<Volunteer> getVolunteersForJob(final Job the_job) throws IllegalArgumentException{
		
		if(the_job == null) {
			throw new IllegalArgumentException("Job cannot be null");
		}
		
		return the_job.getVolunteers();
		
	}
	
	/*
	 * @pre: my_current_user != null
	 * @pre: my_current_user == ParkManager
	 * 
	 * @post: all jobs related to the park manager will be returned.
	 */
	/**
	 * This method returns a list of jobs associated with a park managers parks.
	 * @return returns a collection of jobs within each park the park manager manages.
	 * @throws IllegalArgumentException if the user is not a park manager.
	 */
	public Collection<Job> getJobsForParkManager() throws IllegalArgumentException{
		
		Collection<Job> jobs = new ArrayList<Job>();
		
		if(my_current_user instanceof ParkManager) {
			
			ArrayList<Park> parks = new ArrayList<Park>(((ParkManager)my_current_user).getParks());
			
			for(int i = 0; i < parks.size(); i++) {
				
				jobs.addAll(parks.get(i).getJobs());
			}
			
		} else {
			
			throw new IllegalArgumentException("User is not a Park Manager");
		}
		
		return jobs;
		
	}
	
	/*
	 * @pre: volunteer collection !=null
	 * @post: returns a collection of volunteers
	 */
	/**
	 * This method returns a collection of every volunteer in the system.
	 * @return a collection of volunteers
	 */
	public Collection<Volunteer> getAllVolunteers() {
		
		return my_volunteer_list;
	}
	
	/*
	 * @pre: my_current_user != null
	 * @pre: getParks() !return null
	 * 
	 * @post: returns a collection of parks
	 */
	/**
	 * This method gets all parks the PM handles
	 * @return returns a collection of all parks related to the PM.
	 */
	public Collection<Park> getParksForPM() {
		ArrayList<Park> parks = new ArrayList<Park>();
		
		if(my_current_user instanceof ParkManager) {
			
			parks.addAll(((ParkManager)my_current_user).getParks());
		
		} else {
			throw new IllegalArgumentException("Not a Park Manager");
		}
		
		return parks;
	}
	
	/*
	 * @pre: my_parks_list != null
	 * 
	 * @post: my_total_jobs >= 0;
	 */
	/**
	 * Sets the current number of jobs. this method
	 * gets all open jobs in the system and uses its size to
	 * set total number of jobs.
	 * @param the_num the number of current jobs.
	 */
	public void setTotalJobs() {
		Collection<Job> jobs = new ArrayList<Job>(getOpenJobs());
		my_total_jobs = jobs.size();
	}
	
	/*
	 * @pre: the_num != null
	 * 
	 * @post: my_total_jobs >=0
	 */
	/**
	 * This method is used to set Total jobs directly.
	 * @param the_num
	 */
	public void setTotalJobs(int the_num) {
		
		my_total_jobs = the_num;
	}
	
	/*
	 * @pre: my_total_jobs != null
	 */
	/**
	 * this method returns the number of open jobs in the system.
	 * @return returns an int that represents the total open jobs in the system.
	 */
	public int getTotalJobs() {
		
		return my_total_jobs;
	}
	
	/*
	 * pre: my_park_list != null
	 * 
	 * @post: returns a collection of strings.
	 */
	/**
	 * This method returns a collection of park names as a string.
	 * @return returns a collection of park names.
	 */
	 public Collection<String> getParkNames() {
		 ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
		 Collection<String> names = new ArrayList<String>();
		 for(int i = 0; i < parks.size(); i++) {
			 names.add(parks.get(i).getParkName());
		 }
		 return names;
	 }
	 
	 /*
	  * @pre my_park_list != null
	  * 
	  * @post: returns a collection of jobs that havent passed yet.
	  */
	 /**
	  * This method returns all jobs that are currently open. This also sets
	  * @return returns a collection of jobs that are open.
	  */
	 public Collection<Job> getOpenJobs() {
			Calendar cal = Calendar.getInstance();
			
			Date currentDate = new Date(cal.get(cal.MONTH) + 1, cal.get(cal.DATE), cal.get(cal.YEAR));	
			ArrayList<Job> jobs = new ArrayList<Job>();
			ArrayList<Park> parks = new ArrayList<Park>(my_park_list);
			
			for(int i = 0; i < parks.size(); i++) {
				jobs.addAll(parks.get(i).getJobs());
			}
			
			for(int i = 0; i < jobs.size(); i++) {

				if(jobs.get(i).getStartDate().comesBefore(currentDate)) {
					
					
					jobs.remove(i);
					i--;
				}
			}
			return jobs;
	 }
	 
	 /*
	  * @pre: my_user_map != null
	  * 
	  * @post: returns a list of users.
	  */
	 /**
	  * This method returns a list of users for the GUI to use.
	  * @return a list of users for the GUI
	  */
	 public List<User> getUsers() {
		 
		 ArrayList<String> emails = new ArrayList<String>(my_user_map.keySet());
		 List<User> users = new ArrayList<User>();
		 
		 for(int i = 0; i < emails.size(); i++) {
			 users.add(my_user_map.get(emails.get(i)));
		 }
		 
		 
		 
		 return users;
		 
		 
		 
		 
	 }
}
